//
// defines.h
// libprotea
// Tools Library for the Protea Project / Global definitions
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
//
// theproteaproject@gmail.com 
//

#ifndef __PROTEA_DEFINES_H__
#define __PROTEA_DEFINES_H__

extern const char Protea_VersionId[];

const char copyright[] =
"\n"
"/*----------------------------------------------------------------------------*/\n"
"/* COPYRIGHT NOTICE                                                           */\n"
"/*                                                                            */\n"
"/* Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.                              */\n"
"/* Copyright (C) 2008 Bruce A. James                                          */\n"
"/*                                                                            */\n"
"/* This program is part of the Protea Project.                                */\n"
"/*                                                                            */\n"
"/* The Protea Project is free software; you can redistribute it and/or modify */\n"
"/* it under the terms of the GNU General Public License as published by the   */\n"
"/* Free Software Foundation, either version 3 of the License, or (at your     */\n"
"/* option) any later version.                                                 */\n"
"/*                                                                            */\n"
"/* The Protea Project is distributed in the hope that it will be useful, but  */\n"
"/* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY */\n"
"/* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License    */\n"
"/* for more details.                                                          */\n"
"/*                                                                            */\n"
"/* You should have received a copy of the GNU General Public License along    */\n"
"/* with this program.  If not, see <http://www.gnu.org/licenses/>.            */\n"
"/*                                                                            */\n"
"/* Please send correspondence to:                                             */\n"
"/*                                                                            */\n"
"/* theproteaproject@gmail.com                                                 */\n"
"/*----------------------------------------------------------------------------*/\n"
;

//
//  Export symbol
//
#ifdef _MSC_VER
#	ifdef PROTEA_IMPORT
#		define __EXPORT __declspec( dllimport )
#	else
#		define __EXPORT __declspec( dllexport )
#	endif
#else
	#define __EXPORT
#endif

// Determine what Operating system we are compiling for
#include "OS_defines.h"

// Common include files, defined here for precompiled header support
#include <assert.h>
#include <memory.h>
#include <string.h>
#include <stdio.h>

#include <iostream>
#include <fstream>

using namespace std;

#define USE_MEM_WATCH
#include "memwatch.h"




/**
	\file defines.h
	\brief Contains all OS dependent macro definitions

	Also includes any needed system header files
*/


// Number of Trace Categories
const int num_tc = 10;


//
// Output operating system target
//
#ifdef OS_WIN32
	// Intel compiler appears to have problems with the crtdbg library
#	if defined(_DEBUG) && !defined( __ICC )
#		define _CRTDBG_MAP_ALLOC
#		include <crtdbg.h>
#		define new new( _NORMAL_BLOCK, __FILE__, __LINE__ )
#	endif
#endif


//
// Definition of 64bit integers
//

#ifdef _MSC_VER
	#define QUADCONST(n) (n)
	typedef          __int64 SINT64;
	typedef unsigned __int64 UINT64;
#else
	#define QUADCONST(n) (n##LL)
	typedef          long long int SINT64;
	typedef unsigned long long int UINT64;
#endif


#define MAX_UINT64              ((UINT64) QUADCONST(0xFFFFFFFFFFFFFFFF))
#define MIN_UINT64              QUADCONST(0x0000000000000000)
#define MAX_SINT64              QUADCONST(0x7FFFFFFFFFFFFFFF)
#define MIN_SINT64              (-MAX_SINT64-1)






/// Base class for all Protea Project objects
class __EXPORT XCBase
{
public:
	virtual ~XCBase();

	/// Deletes the object
	virtual void Release() { delete this; };
};


//
// Licensing
// 
#include "licensing.h"




//
// Stack trace
//
#ifndef NOSTACKTRACE
#	include "stacktrace.h"
#else
#	undef INFUNC( func )
#	undef OUTFUNC
#	define INFUNC( func )
#	define OUTFUNC
#endif


//
//	UNICODE support
//
#define _UNICODE



//
// These macros are for use in making Transaction Code more readable.
//     They should not be changed by anyone other than the authors
//
enum Txn_Type
{
	TXN_ADD = 0,
	TXN_CHANGE = 1,
	TXN_DELETE = 2,
	TXN_REVIEW = 3
};

#define TRANSACTION(x)	XCTransactionInfo* x( XCTransactionInfo* transaction )

#define TRANSACTION_CODE(x)	XCTransactionInfo* x( XCTransactionInfo* transaction )

#define SUB_TXN(x)	void x( XCBuffer* Buf, XCTransactionVars* Vars )

#define SUB_TXN_TYPED(x)	void x( XCBuffer* Buf, XCTransactionVars* Vars, Txn_Type TType )

#define SUB_TXN_REVIEW(x)	void x( XCBuffer* Buf, XCTransactionVars* Vars, bool* Result = NULL )
#define SUB_TXN_REV_CODE(x)	void x( XCBuffer* Buf, XCTransactionVars* Vars, bool* Result )

#define START_TXN(x)															\
	XCAppInterface* App = transaction->GetOwner();								\
	EXT_INFUNC( x, App );														\
	XCTransactionVars txnvars( App, transaction, true );						\
	try {																		\
		CLEAR_BUFFER_COUNT;														\
		txnvars.Errors->Check();	// Returns all minimum field length violation errors

#define START_JOB_TXN(x)															\
	XCAppInterface* App = transaction->GetOwner();								\
	EXT_INFUNC( x, App );														\
	XCTransactionVars txnvars( App, transaction, false );						\
	try {																		\
		CLEAR_BUFFER_COUNT;														\
		txnvars.Errors->Check();	// Returns all minimum field length violation errors


/*
#define CLEANUP_TXN_1()															\
	} catch( XCToolsError& err ) {												\

#define CLEANUP_TXN_2()															\
		CHECK_BUFFER_COUNT;														\
		if (err.GetErrorNumber() == 0) {										\
			App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE ); \
			for ( int i = 0; i<txnvars.detailcount; i++ )						\
				App->TransResponse( txnvars.result, txnvars.detail[ i ], TRANS_DETAIL_TYPE ); \
			err.Clear();														\
		} else throw;															\
	} catch(...) {																\

#define CLEANUP_TXN_3()															\
		CHECK_BUFFER_COUNT;														\
		throw;																	\
	};																			\
*/

// If no buffers have been sent, then return what was sent to us
// Also, if error #0 is returned, then clear the error, it means that XCAppErrorHandler
// sent errors and ask to bail out on the transaction.
#define CLEANUP_TXN() }															\
	catch( XCToolsError& err ) {												\
		if (!txnvars.result->BuffersSent()) {									\
			App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE ); \
			for ( int i = 0; i<txnvars.detailcount; i++ )						\
				App->TransResponse( txnvars.result, txnvars.detail[ i ], TRANS_DETAIL_TYPE ); \
		};																		\
		if (err.GetErrorNumber() == 0) {										\
			err.Clear();														\
		} else {																\
			txnvars.Errors->Add( err );											\
			txnvars.result->SetSuccess( false );								\
		};																		\
	} catch( ... ) {															\
		txnvars.Errors->Add( -1 );												\
	}

#define CLEANUP_TXN_1() if (0) { ;
#define CLEANUP_TXN_2() } else if (0) { ;
#define CLEANUP_TXN_3() };	CLEANUP_TXN();

#define END_TXN()																\
	txnvars.Errors->Finish();													\
	CHECK_BUFFER_COUNT;															\
	EXT_OUTFUNCRET( txnvars.ReturnResult() );

#define START_DB_TXN()															\
	txnvars.dbtxn = App->GetDatabase()->CreateTxn( transaction->GetSuperTrans() );	\
	try {																		\

#define END_DB_TXN()															\
		txnvars.Errors->Check();												\
		txnvars.dbtxn->EndTxn( true );											\
		txnvars.result->SetSuccess( true );										\
	} catch(...) {																\
		txnvars.dbtxn->EndTxn( false );											\
		throw;																	\
	};

#define CALLTRANS( transnumber, transbuffer, transname )							\
	XCTransactionInfo* calltransretval;												\
	XCTransactionInfo* calltransinfo = new XCTransactionInfo( App, NULL );			\
	calltransinfo->SetTransID( rand() );											\
	calltransinfo->SetTransNumber( transnumber );									\
	XCToolsMessage* calltransdata = new XCToolsMessage( App );						\
	calltransdata->CreateMsg( TRANS_MESSAGE_SIZE + transbuffer->GetSize() );		\
	trans_message* calltranstxn = (trans_message*)calltransdata->GetDataPtr();		\
	calltranstxn->format = transbuffer->GetFormatNumber();							\
	calltranstxn->data_type = TRANS_HEADER_TYPE;									\
	memcpy( calltranstxn->data, transbuffer->GetData(), transbuffer->GetSize() );	\
	calltransinfo->AddMessage( calltransdata );										\
    calltransretval = transname( calltransinfo );									\
	calltransinfo->Release();														\
	calltransretval->Release();														\

// Include error definitions
#include "errorhandler.h"

#endif
